﻿using Microsoft.EntityFrameworkCore;
using nhCore.db;
using nhCore.nhLib.sql;
using nhCore.nMessage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace nhCore
{
    /// <summary>
    /// 环境站列表及在线数
    /// </summary>
    public sealed class DicEnvStat
    {
        /// <summary>
        /// 环境站字典，设备地址为key，设备为值
        /// </summary>
        public Dictionary<byte, Station> EnvStats { get; set; }
        private List<ElementConfig> _elementConfigs;

        private DicEnvStat() 
        {
            using EnvDbContext db = new();
            _elementConfigs = db.ElementConfigs.AsNoTracking().ToList();
            //从数据库中读出设备表和配置表，初始化本对象
            EnvStats = db.Stations.AsNoTracking().ToDictionary(x => x.Id);
            foreach (Station siteDevice in EnvStats.Values)//遍历设备读出要素配置
            {
                string hfBase;
                if (siteDevice.HandshakeFrame.Length > 2)
                {
                    hfBase = string.Concat(siteDevice.HandshakeFrame.AsSpan(0, siteDevice.HandshakeFrame.Length - 2), "00");
                }
                else
                {
                    NMessage.Error($"握手帧应2位以上");
                    return;
                }
                byte? idBase = EnvStats.Values.FirstOrDefault(x => x.HandshakeFrame == hfBase)?.Id;

                List<ElementConfig> list  = db.ElementConfigs
                    .AsNoTracking()
                    .Where(x => x.StationId == siteDevice.Id || x.MappingStationId == siteDevice.Id)
                    .ToList();

                if (idBase != null && idBase != siteDevice.Id)
                {   //有继承基类
                    List<ElementConfig> jcList = db.ElementConfigs
                        .AsNoTracking()
                        .Where(x => x.StationId == idBase)
                        .ToList();
                    jcList.ForEach(x =>
                    {
                        x.StationId = siteDevice.Id;
                        x.MappingStationId = siteDevice.Id;
                    });
                    list.AddRange(jcList);
                }

                foreach (var elementConfig in list.OrderBy(x => x.StationReg))
                {
                    siteDevice.ElementConfigs.Add(elementConfig);

                    SQLite.CheckAndAddColumn(db, nameof(EnvDbContext.Datas), elementConfig.GetDataFieldName(), "REAL");
                }
            }
        }

        public ElementConfig GetElementConfig(byte id, short stationAddress)
        {
            return EnvStats[id].ElementConfigs.Single(x => x.StationReg == stationAddress);
        }

        #region 单例模式
        private static readonly DicEnvStat _dicEnvStat = new();

        //显式的静态构造函数用来告诉C#编译器在其内容实例化之前不要标记其类型
        static DicEnvStat() { }
        //声明一个私有的构造方法，让外部无法调用这个类的构造方法
        //private DicEnvStat() { }

        /// <summary>
        /// 返回对象单例
        /// </summary>
        public static DicEnvStat Singleton
        {
            get { return _dicEnvStat; }
        }
        #endregion
    }
}